﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Text;

namespace WMemoryProfiler
{
    /// <summary>
    /// Memory diff info for a type. It 
    /// </summary>
    [DebuggerDisplay("Instances {InstanceCount} Diff {InstanceCountDiff}, Diff {AllocatedBytesDiff} bytes, {TypeName}")]
    public class InstanceInfoDiff
    {
        /// <summary>
        /// Current instance count
        /// </summary>
        public int InstanceCount { get; private set; }

        /// <summary>
        /// New total allocated managed object size on managed heap
        /// </summary>
        public long AllocatedBytes { get; private set; }

        /// <summary>
        /// First measured instance cound
        /// </summary>
        public int OldInstanceCount { get; private set; }

        /// <summary>
        /// First measured total object size on managed heap
        /// </summary>
        public long OldAllocatedBytes { get; private set; }

        /// <summary>
        /// Type name of managed type on GC heap
        /// </summary>
        public string TypeName { get; private set; }

        /// <summary>
        /// Difference of NewCount-OldCount
        /// </summary>
        public int InstanceCountDiff
        {
            get { return InstanceCount - OldInstanceCount; }
        }

        /// <summary>
        /// Difference in managed object heap allocation size
        /// </summary>
        public long AllocatedBytesDiff
        {
            get { return AllocatedBytes - OldAllocatedBytes; }
        }
        
        /// <summary>
        /// Initialized a new InstanceInfoDiff instance
        /// </summary>
        /// <param name="instanceCount"></param>
        /// <param name="oldInstanceCount"></param>
        /// <param name="allocatedBytes"></param>
        /// <param name="oldAllocationBytes"></param>
        /// <param name="typeName"></param>
        public InstanceInfoDiff(int instanceCount, int oldInstanceCount, long allocatedBytes, long oldAllocationBytes, string typeName)
        {
            InstanceCount = instanceCount;
            OldInstanceCount = oldInstanceCount;
            AllocatedBytes = allocatedBytes;
            OldAllocatedBytes = oldAllocationBytes;
            TypeName = typeName;
        }

        /// <summary>
        /// For usage with Excel make it a CSV line
        /// </summary>
        /// <returns></returns>
        public string ToCsv()
        {
            return String.Join(";", new string[] { TypeName,
                                                   InstanceCount.ToString(CultureInfo.InvariantCulture), 
                                                   OldInstanceCount.ToString(CultureInfo.InvariantCulture), 
                                                   AllocatedBytes.ToString(CultureInfo.InvariantCulture), 
                                                   OldAllocatedBytes.ToString(CultureInfo.InvariantCulture), 
                                                   InstanceCountDiff.ToString(CultureInfo.InvariantCulture), 
                                                   AllocatedBytesDiff.ToString(CultureInfo.InvariantCulture) });
        }

        /// <summary>
        /// For usage with Excel print this as header first
        /// </summary>
        public static string CsvHeader
        {
            get
            {
                return "Type;InstanceCount;OldInstanceCount;AllocatedBytes;OldAllocatedBytes;InstanceCountDiff;AllocatedBytesDiff";
            }
        }
    }
}
